home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 June / ccd0605.iso / Software / Freeware / Programare / zoomsearch / zoomsearch.exe / {app} / scripts / PHP or ASP / search.asp < prev    next >
Text File  |  2005-03-10  |  62KB  |  1,551 lines

  1. <%@ LANGUAGE="VBScript" %>
  2. <!-- #include file="settings.asp" -->
  3. <%
  4. ' ----------------------------------------------------------------------------
  5. ' Zoom Search Engine 4.0 (10/3/2005)
  6. ' Standard version for ASP
  7. ' A fast custom website search engine
  8. ' Copyright (C) Wrensoft 2000 - 2003
  9. '
  10. ' email: zoom@wrensoft.com
  11. ' www: http://www.wrensoft.com
  12. ' ----------------------------------------------------------------------------
  13. if (ScriptEngine <> "VBScript" OR ScriptEngineMajorVersion < 5) then
  14.     Response.Write("This script requires VBScript 5.5 or later installed on the web server. Please download the latest Windows Script package from Microsoft and install this on your server, or consult your web host<br />")
  15.     Response.End
  16. end if
  17. if (ScriptEngineMajorVersion = 5 AND ScriptEngineMinorVersion < 5 AND AllowExactPhrase = 1) then
  18.     Response.Write("This script requires VBScript 5.5 or later installed on the web server. Please download the latest Windows Script package from Microsoft and install this on your server, or consult your web host<br />")
  19.     Response.Write("Note that you may be able to run this on VBScript 5.1 if you have Exact Phrase matching disabled.<br />")
  20.     Response.End
  21. end if
  22.  
  23. Function MapPath(path)        
  24.     on error resume next 
  25.     IsHSP = Server.IsHSPFile
  26.     if (err.Number = 0 AND IsHSP) then         
  27.         MapPath = Server.MapExternalPath(path) ' for HSP support
  28.     else
  29.         MapPath = Server.MapPath(path)            
  30.     end if    
  31.     on error goto 0
  32. End Function
  33.  
  34. ' Check for dependant files
  35. set fso = CreateObject("Scripting.FileSystemObject")
  36. if (fso.FileExists(MapPath("settings.asp")) = False OR fso.FileExists(MapPath("zoom_wordmap.zdat")) = FALSE OR    fso.FileExists(MapPath("zoom_dictionary.zdat")) = FALSE OR fso.FileExists(MapPath("zoom_pages.zdat")) = FALSE OR fso.FileExists(MapPath("zoom_titles.zdat")) = FALSE) then
  37.     Response.Write("<b>Zoom files missing error:</b> Zoom is missing one or more of the required index data files.<br />Please make sure the generated index files are uploaded to the same path as this search script.<br />")
  38.     Response.End
  39. end if
  40.  
  41. ' ----------------------------------------------------------------------------
  42. ' Settings
  43. ' ----------------------------------------------------------------------------
  44.  
  45. ' The options available in the dropdown menu for number of results
  46. ' per page
  47. PerPageOptions = Array(10, 20, 50, 100)
  48.  
  49. ' ----------------------------------------------------------------------------
  50. ' Parameter initialisation
  51. ' ----------------------------------------------------------------------------
  52. if (Len(Charset) > 0) then
  53.     Response.Charset = Charset
  54. end if
  55.  
  56. ' we use the method=GET and 'query' parameter now (for sub-result pages etc)
  57. if Request.QueryString("zoom_query").Count <> 0 then
  58.     query = Request.QueryString("zoom_query")
  59. end if
  60.  
  61. ' number of results per page, defaults to 10 if not specified
  62. if Request.QueryString("zoom_per_page").Count <> 0 then
  63.     per_page = Request.QueryString("zoom_per_page")
  64. else
  65.     per_page = 10
  66. end if
  67.  
  68. ' current result page number, defaults to the first page if not specified
  69. NewSearch = 0
  70. if Request.QueryString("zoom_page").Count <> 0 then
  71.     page = Request.QueryString("zoom_page")
  72. else
  73.     page = 1
  74.     NewSearch = 1
  75. end if
  76.  
  77. ' AND operator.
  78. ' 1 if we are searching for ALL terms
  79. ' 0 if we are searching for ANY terms (default)
  80. if Request.QueryString("zoom_and").Count <> 0 then
  81.     andq = Request.QueryString("zoom_and")
  82. elseif (IsEmpty(DefaultToAnd) = false AND DefaultToAnd = 1) then
  83.     andq = 1
  84. else
  85.     andq = 0
  86. end if
  87.  
  88. ' categories
  89. if Request.QueryString("zoom_cat").Count <> 0 then
  90.     cat = Int(Request.QueryString("zoom_cat"))
  91. else
  92.     cat = -1
  93. end if
  94.  
  95. ' for sorting options
  96. ' zero is default (relevance)
  97. ' 1 is sort by date (if date/time data is available)
  98. if Request.QueryString("zoom_sort").Count <> 0 then
  99.     sort = Int(Request.QueryString("zoom_sort"))
  100. else
  101.     sort = 0
  102. end if
  103.  
  104. if (IsEmpty(LinkBackURL)) then
  105.     selfURL = Request.ServerVariables("URL")
  106. else
  107.     selfURL = LinkBackURL
  108. end if
  109.  
  110. target = ""
  111. if (UseLinkTarget = 1) then
  112.     target = " target=""" & LinkTarget & """ "
  113. end if
  114.  
  115. Sub PrintEndOfTemplate
  116.     'Let others know about Zoom.
  117.     if (ZoomInfo = 1) then
  118.         Response.Write("<center><p><small>" & STR_POWEREDBY & " <a href=""http://www.wrensoft.com/zoom/"" target=""_blank""><b>Zoom Search Engine</b></a></small></p></center>") & VbCrlf
  119.     end if
  120.     if (UBound(Template) > 0) then
  121.         'If rest of template exists
  122.         Response.Write(Template(1)) & VbCrLf
  123.     end if
  124. End Sub
  125.  
  126.  
  127. ' Translate a wildcard pattern to a regexp pattern
  128. ' Supports '*' and '?' only at the moment.
  129. Function pattern2regexp(pattern)
  130.     ' ASP/VBScript's RegExp has some 7-bit ASCII char issues
  131.     ' and treats accented characters as an end of word for boundaries ("\b")
  132.     ' So we use ^ and $ instead, since we're matching single words anyway
  133.  
  134.     if (InStr(pattern, "#") <> False) then
  135.         pattern = Replace(pattern, "#", "\#")
  136.     end if
  137.  
  138.     if (InStr(pattern, "$") <> False) then
  139.         pattern = Replace(pattern, "$", "\$")
  140.     end if
  141.  
  142.     pattern = Replace(pattern, ".", "\.")
  143.     pattern = Replace(pattern, "*", "[\d\S]*")
  144.     pattern = Replace(pattern, "?", ".")
  145.     pattern2regexp = pattern
  146.  
  147. End Function
  148.  
  149. 'Returns true if a value is found within the array
  150. Function IsInArray(strValue, arrayName)
  151.     Dim iLoop, bolFound
  152.     IsInArray = False
  153.     if (IsArray(arrayName) = False) then
  154.         Exit Function
  155.     End if
  156.     For iLoop = LBound(arrayName) to UBound(arrayName)
  157.         if (CStr(arrayName(iLoop)) = CStr(strvalue)) then
  158.             IsInArray = True
  159.             Exit Function
  160.         end if
  161.     Next
  162. End Function
  163.  
  164. Sub SkipSearchWord(sw)
  165.     if (SearchWords(sw) <> "") then
  166.         if (SkippedWords > 0) then
  167.             SkippedOutputStr = SkippedOutputStr & ", "
  168.         end if
  169.         SkippedOutputStr = SkippedOutputStr & """<b>" & SearchWords(sw) & "</b>"""
  170.         SearchWords(sw) = ""
  171.     end if
  172.     SkippedWords = SkippedWords + 1
  173. End Sub
  174.  
  175. Function PrintHighlightDescription(line)
  176.  
  177.     For i = 0 to numwords-1
  178.         if Len(SearchWords(i)) > 0 then
  179.             if (SearchAsSubstring = 1) then
  180.                 regExp.Pattern = "(" & SearchWords(i) & ")"
  181.                 line = regExp.Replace(line, "[;:]$1[:;]")
  182.             else
  183.                 regExp.Pattern = "(\W|^|\b)(" & SearchWords(i) & ")(\W|$|\b)"
  184.                 line = regExp.Replace(line, "$1[;:]$2[:;]$3")
  185.             end if
  186.         end if
  187.     Next
  188.  
  189.     line = replace(line, "[;:]", "<span class=""highlight"">")
  190.     line = replace(line, "[:;]", "</span>")
  191.     Response.Write(line)
  192. End Function
  193.  
  194. Function PrintNumResults(num)
  195.     if (num = 0) then
  196.         PrintNumResults = STR_NO_RESULTS
  197.     elseif (num = 1) then
  198.         PrintNumResults = num & " " & STR_RESULT
  199.     else
  200.         PrintNumResults = num & " " & STR_RESULTS
  201.     end if
  202. End Function
  203.  
  204. Function SplitMulti(string, delimiters)
  205.     For i = 1 to UBound(delimiters)
  206.         string = Replace(string, delimiters(i), delimiters(0))
  207.     Next
  208.     string = Trim(string)   'for replaced quotes
  209.     SplitMulti = Split(string, delimiters(0))
  210. End Function
  211.  
  212. Sub ShellSort(array)
  213.     last = UBound(array, 2)
  214.     first = LBound(array, 2)
  215.     num = last - first + 1
  216.     ' find the best value for distance
  217.     do
  218.         distance = distance * 3 + 1
  219.     loop until (distance > num)
  220.     do
  221.         distance = distance \ 3
  222.         for index = (distance + first) to last
  223.             value = array(1, index)
  224.             value0 = array(0, index)
  225.             value2 = array(2, index)
  226.             value3 = array(3, index)
  227.             value4 = array(4, index)
  228.             value5 = array(5, index)
  229.             index2 = index
  230.             do while (index2 - distance => first)
  231.                 if (array(2, index2 - distance) > value2) then
  232.                     exit do
  233.                 end if
  234.                 if (array(2, index2 - distance) = value2) then
  235.                     if (array(1, index2 - distance) >= value) then
  236.                         exit do
  237.                     end if
  238.                 end if
  239.                 array(0, index2) = array(0, index2 - distance)
  240.                 array(1, index2) = array(1, index2 - distance)
  241.                 array(2, index2) = array(2, index2 - distance)
  242.                 array(3, index2) = array(3, index2 - distance)
  243.                 array(4, index2) = array(4, index2 - distance)
  244.                 array(5, index2) = array(5, index2 - distance)
  245.                 index2 = index2 - distance
  246.             loop
  247.             array(1, index2) = value
  248.             array(0, index2) = value0
  249.             array(2, index2) = value2
  250.             array(3, index2) = value3
  251.             array(4, index2) = value4
  252.             array(5, index2) = value5
  253.         next
  254.     loop until distance = 1
  255. End Sub
  256.  
  257. Sub ShellSortByDate(array, datetime)
  258.     last = UBound(array, 2)
  259.     first = LBound(array, 2)
  260.     num = last - first + 1
  261.     ' find the best value for distance
  262.     do
  263.         distance = distance * 3 + 1
  264.     loop until (distance > num)
  265.     do
  266.         distance = distance \ 3
  267.         for index = (distance + first) to last
  268.             value = array(1, index)
  269.             value0 = array(0, index)
  270.             value2 = array(2, index)
  271.             value3 = array(3, index)
  272.             value4 = array(4, index)
  273.             value5 = array(5, index)
  274.             index2 = index
  275.             do while (index2 - distance => first)
  276.                 if (cdate(datetime(array(0, index2 - distance))) > cdate(datetime(value0))) then
  277.                     exit do
  278.                 end if
  279.                 if (cdate(datetime(array(0, index2 - distance))) = cdate(datetime(value0))) then
  280.                     if (array(2, index2 - distance) >= value2) then
  281.                         exit do
  282.                     end if
  283.                 end if
  284.                 array(0, index2) = array(0, index2 - distance)
  285.                 array(1, index2) = array(1, index2 - distance)
  286.                 array(2, index2) = array(2, index2 - distance)
  287.                 array(3, index2) = array(3, index2 - distance)
  288.                 array(4, index2) = array(4, index2 - distance)
  289.                 array(5, index2) = array(5, index2 - distance)
  290.                 index2 = index2 - distance
  291.             loop
  292.             array(1, index2) = value
  293.             array(0, index2) = value0
  294.             array(2, index2) = value2
  295.             array(3, index2) = value3
  296.             array(4, index2) = value4
  297.             array(5, index2) = value5
  298.         next
  299.     loop until distance = 1
  300. End Sub
  301.  
  302.  
  303. Function GetBytes(binfile, bytes)
  304.     bytes_buffer = binfile.Read(bytes)
  305.     GetBytes = 0
  306.     bytes_count = LenB(bytes_buffer)
  307.     for k = 1 to bytes_count
  308.         GetBytes = GetBytes +  Ascb(Midb(bytes_buffer, k, 1)) * (256^(k-1))
  309.     next
  310. End Function
  311.  
  312. Function GetNextDictWord(bin_pagetext)
  313.     GetNextDictWord = 0
  314.     do
  315.         dict_id = GetBytes(bin_pagetext, 2)
  316.         GetNextDictWord = GetNextDictWord + dict_id
  317.     loop while (dict_id >= 65535 AND bin_pagetext.EOS <> True)
  318. End Function
  319.  
  320. Function GetDictID(word)
  321.     GetDictID = -1
  322.     for i = 0 to dict_count
  323.         if (LCase(dict(0, i)) = LCase(word)) then
  324.             GetDictID = i
  325.             exit for
  326.         end if
  327.     next
  328. End Function
  329.  
  330. ' Custom read file method to avoid TextStream's ReadAll function
  331. ' which fails to scale reliably on certain machines/setups.
  332. function ReadDatFile(fso, filename)
  333.     set fileObj = fso.GetFile(MapPath(filename))
  334.     set tsObj = fileObj.OpenAsTextStream(1, 0)
  335.     ReadDatFile = tsObj.Read(fileObj.Size)
  336.     tsObj.Close
  337. end function
  338.  
  339. function GetSPCode(word)
  340.  
  341.     ' initialize return variable
  342.     GetSPCode = ""
  343.  
  344.     tmpword = LCase(word)
  345.  
  346.     'strip out non alphabetic characters
  347.     regExp.Pattern = "[^a-z]"
  348.     tmpword = regExp.Replace(tmpword, "")
  349.  
  350.     wordlen = Len(tmpword)
  351.     if wordlen < 1 then
  352.         Exit Function
  353.     end if
  354.  
  355.     GetSPCode = Left(tmpword, 1)
  356.  
  357.     tmpword = Right(tmpword, wordlen-1)
  358.  
  359.     tmpword = Replace(tmpword, "a", "0")
  360.     tmpword = Replace(tmpword, "e", "0")
  361.     tmpword = Replace(tmpword, "i", "0")
  362.     tmpword = Replace(tmpword, "o", "0")
  363.     tmpword = Replace(tmpword, "u", "0")
  364.     tmpword = Replace(tmpword, "h", "0")
  365.     tmpword = Replace(tmpword, "w", "0")
  366.     tmpword = Replace(tmpword, "y", "0")
  367.  
  368.     tmpword = Replace(tmpword, "b", "1")
  369.     tmpword = Replace(tmpword, "p", "1")
  370.     tmpword = Replace(tmpword, "f", "1")
  371.     tmpword = Replace(tmpword, "v", "1")
  372.  
  373.     tmpword = Replace(tmpword, "c", "2")
  374.     tmpword = Replace(tmpword, "g", "2")
  375.     tmpword = Replace(tmpword, "j", "2")
  376.     tmpword = Replace(tmpword, "k", "2")
  377.     tmpword = Replace(tmpword, "q", "2")
  378.     tmpword = Replace(tmpword, "s", "2")
  379.     tmpword = Replace(tmpword, "x", "2")
  380.     tmpword = Replace(tmpword, "z", "2")
  381.  
  382.     tmpword = Replace(tmpword, "d", "3")
  383.     tmpword = Replace(tmpword, "t", "3")
  384.  
  385.     tmpword = Replace(tmpword, "l", "4")
  386.  
  387.     tmpword = Replace(tmpword, "m", "5")
  388.     tmpword = Replace(tmpword, "n", "5")
  389.  
  390.     tmpword = Replace(tmpword, "r", "6")
  391.  
  392.     ' Remove any adjacent digits
  393.     char = ""
  394.     nextChar = ""
  395.     tmpstr = ""
  396.     for i = 1 to wordlen
  397.         char = Mid(tmpword, i, 1)
  398.         nextChar = Mid(tmpword, (i + 1), 1)
  399.         if (IsNumeric(char) AND char <> nextChar) then
  400.             tmpstr = tmpstr + char
  401.         end if
  402.     next
  403.     tmpword = tmpstr
  404.  
  405.     If (Len(tmpword) < 1) Then
  406.         Exit Function
  407.     End If
  408.  
  409.     tmpword = Replace(tmpword, "0", "")
  410.  
  411.     ' Pad to 4 characters with zeroes
  412.     if (Len(tmpword) < 4) then
  413.         tmpword = tmpword & "0000"
  414.     end if
  415.  
  416.     GetSPCode = GetSPCode & Mid(tmpword, 1, 3)
  417. end function
  418.  
  419. ' Debug stop watches to time performance of sub-sections
  420. Dim StopWatch(10)
  421. TimerCount = 0
  422. DebugTimerSum = 0
  423. sub StartTimer()
  424.     StopWatch(TimerCount) = timer
  425.     TimerCount = TimerCount + 1
  426. end sub
  427. function StopTimer()
  428.     EndTime = Timer
  429.     TimerCount = TimerCount - 1
  430.     StopTimer = EndTime - StopWatch(TimerCount)
  431. end function
  432.  
  433. ' ----------------------------------------------------------------------------
  434. ' Main starts here
  435. ' ----------------------------------------------------------------------------
  436.  
  437. ' For timing of the search
  438. if (Timing = 1 OR Logging = 1) then
  439.     Dim StartTime, ElapsedTime
  440.     StartTime = Timer
  441. end if
  442.  
  443. 'Open and print start of result page template
  444. set fp_template = fso.OpenTextFile(MapPath(TemplateFilename), 1)
  445. ' find the "<!--ZOOMSEARCH-->" string in the template html file
  446. dim line, templateFile
  447. do while fp_template.AtEndOfStream <> True
  448.     line = fp_template.ReadLine & VbCrLf
  449.     templateFile = templateFile & line
  450. loop
  451. fp_template.Close
  452. Template = split(templateFile, "<!--ZOOMSEARCH-->")
  453. Response.Write(Template(0)) & VbCrLf
  454.  
  455. '' Check for category files
  456. if (UseCats = 1) then
  457.     if (fso.FileExists(MapPath("zoom_cats.zdat")) = True) AND (fso.FileExists(MapPath("zoom_catpages.zdat")) = True) then
  458.         ' Loads the entire categories page into an array
  459.         catnames = split(ReadDatFile(fso, "zoom_cats.zdat"), chr(10))
  460.         catpages = split(ReadDatFile(fso, "zoom_catpages.zdat"), chr(10))
  461.     else
  462.         Response.Write("Missing file(s) zoom_cats.zdat and zoom_catpages.zdat required for category enabled search mode")
  463.         Response.End
  464.     end if
  465. end if
  466. Response.Write("<!--Zoom Search Engine " & Version & "-->") & VbCrLf
  467.  
  468. ' Replace the key text <!--ZOOMSEARCH--> with the following
  469. if (FormFormat > 0) then
  470.     ' Insert the form
  471.     Response.Write("<form method=""get"" action=""" & selfURL & """ class=""zoom_searchform"">") & VbCrlf
  472.     Response.Write(STR_FORM_SEARCHFOR & " <input type=""text"" name=""zoom_query"" size=""20"" value=""" & Server.HTMLEncode(query) & """ class=""zoom_searchbox"" />") & VbCrlf
  473.     Response.Write("<input type=""submit"" value=""" & STR_FORM_SUBMIT_BUTTON & """ class=""zoom_button"" /> ") & VbCrlf
  474.     if (FormFormat = 2) then
  475.         Response.Write("<span class=""zoom_options"">" & STR_FORM_RESULTS_PER_PAGE) & VbCrlf
  476.         Response.Write("<select name='zoom_per_page'>") & VbCrlf
  477.         For Each ppo In PerPageOptions
  478.             Response.Write("<option")
  479.             if (Int(ppo) = Int(per_page)) then
  480.                 Response.Write(" selected=""selected""")
  481.             end if
  482.             Response.Write(">" & ppo & "</option>") & VbCrLf
  483.         next
  484.         Response.Write("</select><br /><br />") & VbCrlf
  485.  
  486.         if (UseCats = 1) then
  487.             Response.Write(STR_FORM_CATEGORY & " ") & VbCrlf
  488.             Response.Write("<select name='zoom_cat'>") & VbCrlf
  489.             Response.Write("<option value=""-1"">" & STR_FORM_CATEGORY_ALL & "</option>")
  490.             for i = LBound(catnames) to UBound(catnames)
  491.                 Response.Write("<option value=""" & i & """")
  492.                 if (i = cat) then
  493.                     Response.Write(" selected=""selected""")
  494.                 end if
  495.                 Response.Write(">" & catnames(i) & "</option>")
  496.             Next
  497.             Response.Write("</select>  ") & VbCrlf
  498.         end if
  499.  
  500.         Response.Write(STR_FORM_MATCH & " ")
  501.         if (andq = 0) then
  502.             Response.Write("<input type=""radio"" name=""zoom_and"" value=""0"" checked=""checked"" />" & STR_FORM_ANY_SEARCH_WORDS) & VbCrlf
  503.             Response.Write("<input type=""radio"" name=""zoom_and"" value=""1"" />" & STR_FORM_ALL_SEARCH_WORDS) & VbCrlf
  504.         else
  505.             Response.Write("<input type=""radio"" name=""zoom_and"" value=""0"" />" & STR_FORM_ANY_SEARCH_WORDS) & VbCrlf
  506.             Response.Write("<input type=""radio"" name=""zoom_and"" value=""1"" checked=""checked"" />" & STR_FORM_ALL_SEARCH_WORDS) & VbCrlf
  507.         end if
  508.         Response.Write("<input type=""hidden"" name=""zoom_sort"" value=""" & sort & """ />") & VbCrLf
  509.         Response.Write("</span>") & VbCrlf
  510.     else
  511.         Response.Write("<input type=""hidden"" name=""zoom_per_page"" value=""" & per_page & """ />") & VbCrLf
  512.         Response.Write("<input type=""hidden"" name=""zoom_and"" value=""" & andq & """ />") & VbCrLf
  513.         Response.Write("<input type=""hidden"" name=""zoom_sort"" value=""" & sort & """ />") & VbCrLf
  514.     end if
  515.  
  516.     Response.Write("</form>") & VbCrlf
  517. end if
  518.  
  519. ' Give up early if no search words provided
  520. NoSearch = 0
  521. if (Len(query) = 0) then
  522.     if (FormFormat = 0) then
  523.         Response.Write(STR_NO_QUERY & "<br />")
  524.     end if
  525.     'stop here, but finish off the html
  526.     'call PrintEndOfTemplate
  527.     'Response.End no longer used to allow for search.asp to follow through the original file
  528.     'when it is used in in an #include
  529.     NoSearch = 1
  530. end if
  531.  
  532. if (NoSearch = 0) then
  533.  
  534.     ' Load index data files (*.zdat) ----------------------------------------------
  535.  
  536.     ' Load the entire pages file into an array, all URL's on the site
  537.     urls = split(ReadDatFile(fso, "zoom_pages.zdat"), chr(10))
  538.  
  539.     ' Load the entire page titles file into an array
  540.     titles = split(ReadDatFile(fso, "zoom_titles.zdat"), chr(10))
  541.  
  542.     if (DisplayMetaDesc = 1) then
  543.         descriptions = split(ReadDatFile(fso, "zoom_descriptions.zdat"), chr(10))
  544.         if (descriptions(0) = "This file blank due to indexing configuration.") then
  545.             Response.Write("<b>Zoom config error:</b> The zoom_descriptions.zdat file is not properly created for the search settings specified.<br />Please check that you have re-indexed your site with the search settings selected in the configuration window.<br />")
  546.             Response.End
  547.         end if
  548.     end if
  549.  
  550.     if (UseDateTime = 1 OR DisplayDate = 1) then
  551.         datefile = split(ReadDatFile(fso, "zoom_datetime.zdat"), chr(10))
  552.         dates_count = UBound(datefile)-1
  553.         dim datetime()
  554.         redim datetime(dates_count)
  555.         for i = 0 to dates_count
  556.             datetime(i) = CDate(datefile(i))
  557.         next
  558.     end if
  559.  
  560.     if (DisplayContext = 1 OR AllowExactPhrase = 1) then
  561.         Dim bin_pagetext
  562.         set bin_pagetext = CreateObject("ADODB.Stream")
  563.         bin_pagetext.Type = 1   ' stream type = binary
  564.         bin_pagetext.Open       ' open stream
  565.         bin_pagetext.LoadFromFile MapPath("zoom_pagetext.zdat")  'load file to stream
  566.  
  567.         'check for blank message
  568.         tmpstr = CStr(bin_pagetext.Read(8))
  569.         if (tmpstr = "This") then
  570.             Response.Write("<b>Zoom config error:</b> The zoom_pagetext.zdat file is not properly created for the search settings specified.<br />Please check that you have re-indexed your site with the search settings selected in the configuration window.<br />")
  571.             Response.End
  572.         end if
  573.     end if
  574.  
  575.     ' load in dictionary file
  576.     dictfile = split(ReadDatFile(fso, "zoom_dictionary.zdat"), chr(10))
  577.     dict_count = UBound(dictfile)-1
  578.     dim dict()
  579.     redim dict(2, dict_count)
  580.     for i = 0 to dict_count
  581.         dictline = Split(dictfile(i), " ")
  582.         if (UBound(dictline) = 1) then
  583.             dict(0, i) = dictline(0)
  584.             dict(1, i) = dictline(1)
  585.         end if
  586.     next
  587.     ' re-value dict_count in case of errors in dict file
  588.     dict_count = UBound(dict, 2)
  589.  
  590.  
  591.     ' load in wordmap file
  592.     Dim bfp_wordmap
  593.     set bfp_wordmap = CreateObject("ADODB.Stream")
  594.     bfp_wordmap.Type = 1    'Specify stream type - we want To get binary data.
  595.     bfp_wordmap.Open        'Open the stream
  596.     bfp_wordmap.LoadFromFile MapPath("zoom_wordmap.zdat")
  597.  
  598.  
  599.     'Initialise regular expression object
  600.     set regExp = New RegExp
  601.     regExp.Global = True
  602.     if (ToLowerSearchWords = 0) then
  603.         regExp.IgnoreCase = False
  604.     else
  605.         regExp.IgnoreCase = True
  606.     end if
  607.  
  608.     ' Prepare query for search -----------------------------------------------------
  609.  
  610.     'Split search phrase into words
  611.  
  612.     if (MapAccents = 1) then
  613.         For i = 0 to UBound(NormalChars)
  614.             query = Replace(query, AccentChars(i), NormalChars(i))
  615.         Next
  616.     end if
  617.  
  618.     if (AllowExactPhrase = 0) then
  619.         query = Replace(query, """", " ")
  620.     end if
  621.     if (InStr(WordJoinChars, ".") = False) then
  622.         query = Replace(query, ".", " ")
  623.     end if
  624.     if (InStr(WordJoinChars, "-") = False) then
  625.         query = Replace(query, "-", " ")
  626.     end if
  627.     if (InStr(WordJoinChars, "_") = False) then
  628.         query = Replace(query, "_", " ")
  629.     end if
  630.     if (InStr(WordJoinChars, "'") = False) then
  631.         query = Replace(query, "'", " ")
  632.     end if
  633.     if (InStr(WordJoinChars, "#") = False) then
  634.         query = Replace(query, "#", " ")
  635.     end if
  636.     if (InStr(WordJoinChars, "$") = False) then
  637.         query = Replace(query, "$", " ")
  638.     end if
  639.     if (InStr(WordJoinChars, ",") = False) then
  640.         query = Replace(query, ",", " ")
  641.     end if
  642.  
  643.     ' Strip slashes, sloshes, parenthesis and other regexp elements
  644.     query = Replace(query, "/", " ")
  645.     query = Replace(query, "\", " ")
  646.     query = Replace(query, "(", " ")
  647.     query = Replace(query, ")", " ")
  648.     query = Replace(query, "^", " ")
  649.     query = Replace(query, "[", " ")
  650.     query = Replace(query, "]", " ")
  651.     query = Replace(query, "|", " ")
  652.     query = Replace(query, "+", " ")
  653.     query = Replace(query, "{", " ")
  654.     query = Replace(query, "}", " ")        
  655.  
  656.     ' Split exact phrase terms if found
  657.     dim SearchWords, quote_terms, term
  658.     quote_terms = Array()
  659.     tmp_query = query
  660.     if (InStr(query, """")) then
  661.         regExp.Pattern = """.*?"""
  662.         set quote_terms = regExp.Execute(query)
  663.         tmp_query = regExp.Replace(tmp_query, "")
  664.     end if
  665.     tmp_query = Trim(tmp_query)
  666.     regExp.Pattern = "[\s\+,]+"
  667.     tmp_query = regExp.Replace(tmp_query, " ")
  668.     SearchWords = Split(tmp_query, " ")
  669.     'SearchWords = SplitMulti(tmp_query, Array(" ", "_", "[", "]", "+", ","))
  670.  
  671.  
  672.     i = UBound(SearchWords)
  673.     for each term in quote_terms
  674.         i = i + 1
  675.         redim preserve SearchWords(i)
  676.         SearchWords(i) = Replace(term, """", "")
  677.     next
  678.  
  679.     'Print heading
  680.     Response.Write("<div class=""searchheading"">" & STR_RESULTS_FOR & " " & Server.HTMLEncode(query))
  681.     if (UseCats = 1) then
  682.         if (cat = -1) then
  683.             Response.Write(" " & STR_RESULTS_IN_ALL_CATEGORIES)
  684.         else
  685.             Response.Write(" " & STR_RESULTS_IN_CATEGORY & " """ & catnames(cat) & """")
  686.         end if
  687.     end if
  688.     Response.Write("</div><br />") & VbCrlf
  689.  
  690.     Response.Write("<div class=""results"">") & VbCrLf
  691.  
  692.     ' Begin main search loop ------------------------------------------------------
  693.  
  694.     'Loop through all search words
  695.     numwords = UBound(SearchWords)+1
  696.     outputline = 0
  697.  
  698.     'default to use wildcards
  699.     UseWildCards = 1
  700.  
  701.     ' Check for skipped words in search query
  702.     SkippedWords = 0
  703.     SkippedOutputStr = ""
  704.     SkippedExactPhrase = 0
  705.  
  706.     pagesCount = UBound(urls)
  707.     Dim res_table()
  708.     Redim preserve res_table(5, pagesCount)
  709.  
  710.     matches = 0
  711.  
  712.     relative_pos = 0
  713.     current_pos = 0
  714.  
  715.     dim data
  716.  
  717.     dim phrase_data_count()
  718.     dim phrase_terms_data()
  719.     dim xdata()
  720.     dim countbytes
  721.  
  722.     context_maxgoback = 1
  723.  
  724.     for sw = 0 to numwords-1
  725.  
  726.         bSkipped = False
  727.  
  728.         if (SearchWords(sw) = "") then
  729.             bSkipped = True
  730.         end if
  731.  
  732.         if (len(SearchWords(sw)) < MinWordLen) then
  733.             SkipSearchWord(sw)
  734.             bSkipped = True
  735.         end if
  736.  
  737.         if (bSkipped = False) then
  738.  
  739.             if (ToLowerSearchWords = 1) then
  740.                 SearchWords(sw) = Lcase(SearchWords(sw))
  741.             end if
  742.  
  743.             ExactPhrase = 0
  744.             UseWildCards = 0
  745.             if (AllowExactPhrase = 1 AND InStr(SearchWords(sw), " ") <> 0) then
  746.                 ' initialise exact phrase matching for this search 'term'
  747.                 ExactPhrase = 1
  748.                 phrase_terms = Split(SearchWords(sw), " ")
  749.                 num_phrase_terms = UBound(phrase_terms)
  750.                 if (num_phrase_terms > context_maxgoback) then
  751.                     context_maxgoback = num_phrase_terms
  752.                 end if
  753.  
  754.                 tmpid = 0
  755.                 WordNotFound = 0
  756.                 for j = 0 to num_phrase_terms
  757.                     tmpid = GetDictID(phrase_terms(j))
  758.                     if (tmpid = -1) then
  759.                         WordNotFound = 1
  760.                         exit for
  761.                     end if
  762.                     'Response.Write("dict: " & dict(1, tmpid))
  763.                     wordmap_row =Int(dict(1, tmpid))
  764.                     'Response.Write("wordmap_row:" & wordmap_row)
  765.                     if (wordmap_row <> -1) then
  766.                         bfp_wordmap.Position = wordmap_row
  767.                         if (bfp_wordmap.EOS = True) then
  768.                             exit for
  769.                         end if
  770.                         countbytes = GetBytes(bfp_wordmap, 2) - 1
  771.                         redim preserve phrase_data_count(j)
  772.                         phrase_data_count(j) = countbytes
  773.                         redim xdata(2, countbytes)
  774.                         for xbi = 0 to countbytes
  775.                             xdata(0, xbi) = GetBytes(bfp_wordmap, 2)
  776.                             xdata(1, xbi) = GetBytes(bfp_wordmap, 2)
  777.                             xdata(2, xbi) = GetBytes(bfp_wordmap, 4)
  778.                             redim preserve phrase_terms_data(j)
  779.                             phrase_terms_data(j) = xdata
  780.                         next
  781.                     else
  782.                         redim preserve phrase_data_count(j)
  783.                         phrase_data_count(j) = 0
  784.                     end if
  785.                 next
  786.             ' check whether there are any wildcards used
  787.             elseif (InStr(SearchWords(sw), "*") <> 0 OR InStr(SearchWords(sw), "?") <> 0) then
  788.  
  789.                 patternStr = ""
  790.  
  791.                 if (SearchAsSubstring = 0) then
  792.                     patternStr = patternStr & "^"
  793.                 end if
  794.  
  795.                 ' new keyword pattern to match for
  796.                 SearchWords(sw) = pattern2regexp(SearchWords(sw))
  797.                 patternStr = patternStr & SearchWords(sw)
  798.  
  799.                 if (SearchAsSubstring = 0) then
  800.                     patternStr = patternStr & "$"
  801.                 end if
  802.  
  803.                 regExp.Pattern = patternStr
  804.                 UseWildCards = 1
  805.             end if
  806.  
  807.  
  808.             if (WordNotFound <> 1) then
  809.  
  810.                 'Read in a line at a time from the keywords file
  811.                 for i = 0 to dict_count
  812.  
  813.                     word = dict(0, i)
  814.                     ptr = dict(1, i)
  815.  
  816.                     if (ExactPhrase = 1) then
  817.                         bMatched = phrase_terms(0) = Lcase(word)
  818.                     elseif (UseWildCards = 0) then
  819.                         if (SearchAsSubstring = 0) then
  820.                             bMatched = SearchWords(sw) = Lcase(word)
  821.                         else
  822.                             bMatched = InStr(Lcase(word), SearchWords(sw))
  823.                         end if
  824.                     else
  825.                         bMatched = regExp.Test(word)
  826.                     end if
  827.  
  828.                     ' word found but indicated to be not indexed or skipped
  829.                     if (bMatched AND Int(ptr) = -1) then
  830.                         if (UseWildCards = 0 AND SearchAsSubstring = 0) then
  831.                             SkippedExactPhrase = 1
  832.                             SkipSearchWord(sw)
  833.                             exit for
  834.                         else
  835.                             'continue
  836.                             bMatched = False ' do nothing until next iteration
  837.                         end if
  838.                     end if
  839.  
  840.                     if (bMatched) then
  841.  
  842.                         'keyword found in dictionary
  843.                         if (ExactPhrase = 1) then
  844.                             data_count = phrase_data_count(0)
  845.                             redim data(2, data_count)
  846.                             data = phrase_terms_data(0)
  847.                             ContextSeeks = 0
  848.                         else
  849.                             bfp_wordmap.Position = ptr
  850.                             if (bfp_wordmap.EOS = True) then
  851.                                 exit for
  852.                             end if
  853.                             'first 2 bytes is data count
  854.                             data_count = GetBytes(bfp_wordmap, 2) - 1   ' index from 0
  855.                             redim data(2, data_count)
  856.                             for j = 0 to data_count
  857.                                 'redim preserve data(2, j)
  858.                                 data(0, j) = GetBytes(bfp_wordmap, 2)   'score
  859.                                 data(1, j) = GetBytes(bfp_wordmap, 2)   'pagenum
  860.                                 data(2, j) = GetBytes(bfp_wordmap, 4)   'ptr
  861.                             next
  862.                             if (bfp_wordmap.EOS = True) then
  863.                                 exit for
  864.                             end if
  865.                         end if
  866.  
  867.                         for j = 0 to data_count
  868.                             score = Int(data(0, j))
  869.                             ipage = data(1, j)  'pagenum
  870.                             txtptr = data(2, j)
  871.                             GotoNextPage = 0
  872.                             FoundPhrase = 0
  873.  
  874.                             if (ExactPhrase = 1) then
  875.                                 maxptr = txtptr
  876.                                 maxptr_term = 0
  877.  
  878.                                 ' check if all of the other words in the phrase appears on this page
  879.                                 for xi = 1 to num_phrase_terms
  880.                                     ' see if this word appears at all on this page, if not, we stop scanning page
  881.                                     ' do not check for skipped words (data count value of zero)
  882.                                     if (phrase_data_count(xi) <> 0) then
  883.                                         ' check wordmap for this search phrase to see if it appears on the current page
  884.                                         tmpdata = phrase_terms_data(xi)
  885.                                         for xbi = 0 to phrase_data_count(xi)
  886.                                             if (tmpdata(1, xbi) = data(1, j)) then
  887.                                                 ' intersection, this term appears on both pages, goto next term
  888.                                                 ' remember biggest pointer
  889.                                                 if (tmpdata(2, xbi) > maxptr) then
  890.                                                     maxptr = tmpdata(2, xbi)
  891.                                                     maxptr_term = xi
  892.                                                 end if
  893.                                                 score = score + tmpdata(0, xbi)
  894.                                                 exit for
  895.                                             end if
  896.                                         next
  897.                                         if (xbi > phrase_data_count(xi)) then ' if not found
  898.                                             GotoNextPage = 1
  899.                                             exit for
  900.                                         end if
  901.                                     end if
  902.                                 next
  903.  
  904.                                 if (GotoNextPage <> 1) then
  905.  
  906.                                     ContextSeeks = ContextSeeks + 1
  907.                                     if (ContextSeeks > MaxContextSeeks) then
  908.  
  909.                                         Response.Write("<small>" & STR_PHRASE_CONTAINS_COMMON_WORDS & " <b>""" & SearchWords(sw) & """</b></small><br /><br />")
  910.                                         exit for
  911.                                     end if
  912.  
  913.                                     ' ok so this page contains all the words in the phrase
  914.                                     FoundPhrase = 0
  915.                                     FoundFirstWord = 0
  916.  
  917.                                     ' we goto the first occurance of the first word in pagetext
  918.                                     pos = maxptr - ((maxptr_term+3) * MaxDictIDLen) ' assume 3 possible punct.
  919.                                     ' do not seek further back than the occurance of the first word (avoid wrong page)
  920.                                     if (pos < txtptr) then
  921.                                         pos = txtptr
  922.                                     end if
  923.                                     bin_pagetext.Position = pos
  924.  
  925.                                     bytes_buffer = ""
  926.                                     BufferLen = 256
  927.                                     bytes_read = BufferLen
  928.  
  929.                                     ' now we look for the phrase within the context of this page
  930.                                     Do
  931.                                         for xi = 0 to num_phrase_terms
  932.                                             do
  933.                                                 xword_id = 0
  934.                                                 do
  935.                                                     if (bytes_read >= BufferLen) then
  936.                                                         pos = bin_pagetext.Position
  937.                                                         bytes_buffer = bin_pagetext.Read(BufferLen)
  938.                                                         bytes_read = 0
  939.                                                     end if
  940.                                                     dict_id = 0
  941.                                                     bytes = Midb(bytes_buffer, bytes_read+1, 2)
  942.                                                     for k = 1 to 2
  943.                                                         dict_id = dict_id + Ascb(Midb(bytes, k, 1)) * (256^(k-1))
  944.                                                     next
  945.                                                     xword_id = xword_id + dict_id
  946.                                                     bytes_read = bytes_read + 2
  947.                                                 loop while (dict_id >= 65535)
  948.                                                 'xword_id = GetNextDictWord(bin_pagetext)
  949.  
  950.                                                 if (xword_id = 0 OR xword_id > dict_count) then
  951.                                                     exit for
  952.                                                 end if
  953.                                                 ' if punct. keep reading.
  954.                                             loop while (xword_id <= DictReservedLimit AND bin_pagetext.EOS <> True)
  955.  
  956.                                             if (Lcase(dict(0, xword_id)) <> phrase_terms(xi)) then
  957.                                                 exit for
  958.                                             end if
  959.  
  960.                                             if (xi = 0) then
  961.                                                 FoundFirstWord = FoundFirstWord + 1
  962.                                                 ' remember the position of the 'start' of this phrase
  963.                                                 'txtptr = pos + bytes_read - MaxDictIDLen
  964.                                                 txtptr = pos
  965.                                             end if
  966.                                         next
  967.  
  968.                                         if (xi > num_phrase_terms) then
  969.                                             ' exact phrase found
  970.                                             FoundPhrase = 1
  971.                                         end if
  972.                                     Loop while xword_id <> 0 AND FoundPhrase = 0 AND FoundFirstWord <= score
  973.                                 end if
  974.  
  975.                                 if (FoundPhrase <> 1) then
  976.                                     GotoNextPage = 1
  977.                                 end if
  978.  
  979.                             end if
  980.  
  981.                             ' check whether we should skip to next page or not
  982.  
  983.                             if (GotoNextPage <> 1) then
  984.  
  985.                                 'Check if page is already in output list
  986.                                 pageexists = 0
  987.  
  988.                                 if ipage < 0 OR ipage > pagesCount then
  989.                                     Response.Write("problem: page number too big. stopping.")
  990.                                     exit for
  991.                                 end if
  992.  
  993.                                 if (Int(res_table(0, ipage)) = 0) then
  994.                                     matches = matches + 1
  995.                                     res_table(0, ipage) = Int(res_table(0, ipage)) + score
  996.                                     if (res_table(0, ipage) <= 0) then
  997.                                         Response.Write("Score should not be negative: " & score & "<br />")
  998.                                     end if
  999.  
  1000.                                     res_table(2, ipage) = txtptr
  1001.                                 else
  1002.                                     if (Int(res_table(0, ipage)) > 10000) then
  1003.                                         ' take it easy if its too big (to prevent huge scores)
  1004.                                         res_table(0, ipage) = Int(res_table(0, ipage)) + 1
  1005.                                     else
  1006.                                         res_table(0, ipage) = Int(res_table(0, ipage)) + score
  1007.                                         res_table(0, ipage) = Int(res_table(0, ipage)) * 2
  1008.                                     end if
  1009.  
  1010.                                     'store the next two searchword matches
  1011.                                     if (Int(res_table(1, ipage)) > 0 AND Int(res_table(1, ipage)) < MaxContextKeywords) then
  1012.                                         if (Int(res_table(3, ipage)) = 0) then
  1013.                                             res_table(3, ipage) = txtptr
  1014.                                         elseif (Int(res_table(4, ipage)) = 0) then
  1015.                                             res_table(4, ipage) = txtptr
  1016.                                         end if
  1017.                                     end if
  1018.                                 end if
  1019.  
  1020.                                 ' store the 'total terms matched' value
  1021.                                 res_table(1, ipage) = Int(res_table(1, ipage)) + 1
  1022.  
  1023.                                 ' store the 'AND search terms matched' value
  1024.                                 if (res_table(5, ipage) = sw OR res_table(5, ipage) = sw-SkippedWords) then
  1025.                                     res_table(5, ipage) = Int(res_table(5, ipage)) + 1
  1026.                                 end if
  1027.  
  1028.                             end if
  1029.                         next
  1030.  
  1031.                         if (UseWildCards = 0 AND SearchAsSubstring = 0) then
  1032.                             exit for
  1033.                         end if
  1034.                     end if
  1035.                 next
  1036.             end if
  1037.         end if
  1038.  
  1039.         if (sw <> numwords-1) then
  1040.             bfp_wordmap.Position = 1
  1041.         end if
  1042.     next
  1043.  
  1044.     'Close the keywords file that was being used
  1045.     bfp_wordmap.Close
  1046.  
  1047.     if SkippedWords > 0 then
  1048.         Response.Write("<i>" & STR_SKIPPED_FOLLOWING_WORDS & " " & SkippedOutputStr & "<br />")
  1049.         if (SkippedExactPhrase = 1) then
  1050.             Response.Write(STR_SKIPPED_PHRASE & ".<br />")
  1051.         end if
  1052.         Response.Write("</i><br />")
  1053.     end if
  1054.  
  1055.  
  1056.     oline = 0
  1057.     fullmatches = 0
  1058.     ResFiltered = False
  1059.     dim output()
  1060.     full_numwords = numwords - SkippedWords
  1061.     for i = 0 to pagesCount Step 1
  1062.         IsFiltered = False
  1063.         if (res_table(0, i) > 0) then
  1064.             if (UseCats = 1 AND cat <> -1) then
  1065.                 if (Int(catpages(i)) <> cat) then
  1066.                     IsFiltered = True
  1067.                 end if
  1068.             end if
  1069.  
  1070.             if (IsFiltered = False) then
  1071.                 'if (res_table(1, i) >= full_numwords) then
  1072.                 if (res_table(5, i) >= full_numwords) then
  1073.                     fullmatches = fullmatches + 1
  1074.                 elseif (andq = 1) then
  1075.                     ' AND search, filter out non-matching results
  1076.                     IsFiltered = True
  1077.                 end if
  1078.             end if
  1079.  
  1080.             if (IsFiltered = False) then
  1081.                 ' copy if not filtered out
  1082.                 redim preserve output(5, oline)
  1083.                 output(0, oline) = i
  1084.                 output(1, oline) = res_table(0, i)
  1085.                 output(2, oline) = res_table(1, i)
  1086.                 output(3, oline) = res_table(2, i)
  1087.                 output(4, oline) = res_table(3, i)
  1088.                 output(5, oline) = res_table(4, i)
  1089.                 oline = oline + 1
  1090.             else
  1091.                 ResFiltered = True
  1092.             end if
  1093.         end if
  1094.     Next
  1095.  
  1096.     If (ResFiltered = True) then
  1097.         matches = oline
  1098.     End if
  1099.  
  1100.     ' Sort the results
  1101.     if (matches > 1) then
  1102.         lobound = LBound(output, 2)
  1103.         hibound = UBound(output, 2)
  1104.         if (sort = 1 AND UseDateTime = 1) then
  1105.             call ShellSortByDate(output, datetime)
  1106.         else
  1107.             call ShellSort(output)
  1108.         end if
  1109.     end if
  1110.  
  1111.     ' query_out is the query prepared to be passed in a URL.
  1112.     query_out = Server.URLEncode(query)
  1113.  
  1114.     'Display search results
  1115.     Response.Write("<div class=""summary"">")
  1116.     if matches = 0 Then
  1117.         Response.Write(STR_SUMMARY_NO_RESULTS_FOUND)
  1118.     elseif numwords > 1 AND andq = 0 then
  1119.         SomeTermMatches = matches - fullmatches
  1120.         Response.Write(PrintNumResults(fullmatches) & " " & STR_SUMMARY_FOUND_CONTAINING_ALL_TERMS & " ")
  1121.         if (SomeTermMatches > 0) then
  1122.             Response.Write(PrintNumResults(SomeTermMatches) & " " & STR_SUMMARY_FOUND_CONTAINING_SOME_TERMS)
  1123.         end if
  1124.     elseif numwords > 1 AND andq = 1 then
  1125.         Response.Write(PrintNumResults(fullmatches) & " " & STR_SUMMARY_FOUND_CONTAINING_ALL_TERMS)
  1126.     else
  1127.         Response.Write(PrintNumResults(matches) & " " & STR_SUMMARY_FOUND)
  1128.     end if
  1129.     Response.Write("<br />")
  1130.  
  1131.     if (matches < 3) then
  1132.         if (andq = 1 AND numwords > 1) then
  1133.             Response.Write("<br />" & STR_POSSIBLY_GET_MORE_RESULTS & " <a href=""" & SelfURL & "?zoom_query=" & query_out & "&zoom_page=" & page & "&zoom_per_page=" & per_page & "&zoom_cat=" & cat & "&zoom_and=0" & "&zoom_sort=" & sort & """>" & STR_ANY_OF_TERMS & "</a>.<br />")
  1134.         elseif (UseCats = 1 AND cat <> -1) then
  1135.             Response.Write("<br />" & STR_POSSIBLY_GET_MORE_RESULTS & " <a href=""" & SelfURL & "?zoom_query=" & query_out & "&zoom_page=" & page & "&zoom_per_page=" & per_page & "&zoom_cat=-1" & "&zoom_and=" & andq & "&zoom_sort=" & sort & """>" & STR_ALL_CATS & "</a>.<br />")
  1136.         end if
  1137.     end if
  1138.     Response.Write("</div>") & VbCrlf
  1139.  
  1140.     if (Spelling = 1 AND matches < SpellingWhenLessThan) then
  1141.  
  1142.         ' load in spellings file
  1143.         spellfile = split(ReadDatFile(fso, "zoom_spelling.zdat"), chr(10))
  1144.         spell_count = UBound(spellfile)-1
  1145.         dim spell()
  1146.         redim spell(2, spell_count)
  1147.         for i = 0 to spell_count
  1148.             sp_line = Split(spellfile(i), " ")
  1149.             if (UBound(sp_line) = 1) then
  1150.                 spell(0, i) = sp_line(0)
  1151.                 spell(1, i) = sp_line(1)
  1152.             end if
  1153.         next
  1154.         ' re-value spell_count in case of errors in dict file
  1155.         spell_count = UBound(spell, 2)
  1156.  
  1157.         SuggestionsCount = 0
  1158.         SuggestStr = ""
  1159.  
  1160.         for sw = 0 to numwords-1
  1161.             ' word does not match, check if it is a candidate to be a suggestion
  1162.             sw_spcode = GetSPCode(SearchWords(sw))
  1163.  
  1164.             if (Len(sw_spcode) = 4) then
  1165.                 SuggestionFound = 0
  1166.                 for i = 0 to spell_count
  1167.  
  1168.                     spcode = spell(0, i)
  1169.                     dictid = spell(1, i)
  1170.  
  1171.                     word = dict(0, dictid)
  1172.                     ptr = dict(1, dictid)
  1173.  
  1174.                     if (spcode = sw_spcode) then
  1175.                         if ((Int(ptr) = -1) OR (LCase(word) = LCase(SearchWords(sw)))) then
  1176.                             ' Check that it is not a skipped word or the same word
  1177.                             SuggestionFound = 0
  1178.                             exit for
  1179.                         else
  1180.                             SuggestionFound = 1
  1181.                             SuggestionsCount = SuggestionsCount + 1
  1182.                         end if
  1183.                     elseif (spcode > sw_spcode) then
  1184.                         exit for
  1185.                     end if
  1186.                     if (SuggestionFound = 1) then
  1187.                         exit for
  1188.                     end if
  1189.                 next
  1190.  
  1191.                 if (sw > 0) then
  1192.                     SuggestStr = SuggestStr & " "
  1193.                 end if
  1194.  
  1195.                 if (SuggestionFound = 1) then
  1196.                     SuggestStr = SuggestStr & word  ' add string AFTER so we can preserve order of words
  1197.                 else
  1198.                     SuggestStr = SuggestStr & SearchWords(sw)
  1199.                 end if
  1200.  
  1201.             end if
  1202.         next
  1203.  
  1204.  
  1205.         if (SuggestionsCount > 0) then
  1206.             suggeststr_out = Server.URLEncode(SuggestStr)
  1207.             Response.Write("<br />" & STR_DIDYOUMEAN & " <a href=""" & SelfURL & "?zoom_query=" & suggeststr_out & "&zoom_page=" & page & "&zoom_per_page=" & per_page & "&zoom_cat=" & cat & "&zoom_and=0&zoom_sort=" & sort & """>" & SuggestStr & "</a>?<br />")
  1208.         end if
  1209.     end if
  1210.  
  1211.  
  1212.     ' Number of pages of results
  1213.     ' Round up numbers with CLng note that it rounds to nearest whole number, ie: 0.5 -> 0, 1.5 -> 2
  1214.     if (matches MOD per_page = 0) then
  1215.         'whole number
  1216.         num_pages = CLng(matches / per_page)
  1217.     else
  1218.         'unwholey number
  1219.         num_pages = CLng((matches / per_page) + 0.5)
  1220.     end if
  1221.  
  1222.     if (num_pages > 1) then
  1223.         Response.Write("<br />" & num_pages & " " & STR_PAGES_OF_RESULTS & "<br />") & VbCrlf
  1224.     end if
  1225.  
  1226.     ' Show sorting options
  1227.     if (matches > 1 AND UseDateTime = 1) then
  1228.         Response.Write("<div class=""sorting"">")
  1229.         if (sort = 1) then
  1230.             Response.Write("<a href=""" & SelfURL & "?zoom_query=" & query_out & "&zoom_page=" & page & "&zoom_per_page=" & per_page & "&zoom_cat=" & cat & "&zoom_and=" & andq & "&zoom_sort=0"">" & STR_SORTBY_RELEVANCE & "</a> / <b>" & STR_SORTEDBY_DATE & "</b>")
  1231.         else
  1232.             Response.Write("<b>" & STR_SORTEDBY_RELEVANCE & "</b> / <a href=""" & SelfURL & "?zoom_query=" & query_out & "&zoom_page=" & page & "&zoom_per_page=" & per_page & "&zoom_cat=" & cat & "&zoom_and=" & andq & "&zoom_sort=1"">" & STR_SORTBY_DATE & "</a>")
  1233.         end if
  1234.         Response.Write("</div>")
  1235.     end if
  1236.  
  1237.  
  1238.     ' Determine current line of result from the $output array
  1239.     if (page = 1) then
  1240.         arrayline = 0
  1241.     else
  1242.         arrayline = (page - 1) * per_page
  1243.     end if
  1244.  
  1245.     ' The last result to show on this page
  1246.     result_limit = arrayline + per_page
  1247.  
  1248.     ' Display the results
  1249.     do while (arrayline < matches AND arrayline < result_limit)
  1250.         ipage = output(0, arrayline)
  1251.         score = output(1, arrayline)
  1252.  
  1253.         Response.Write("<p></p>") & VbCrLf
  1254.  
  1255.         Response.Write("<div class=""result_title"">")
  1256.         if (DisplayNumber = 1) then
  1257.             Response.Write("<b>" & (arrayline+1) & ".</b> ")
  1258.         end if
  1259.  
  1260.         if (DisplayTitle = 1) then
  1261.             if (GotoHighlight = 1) then
  1262.                 if (SearchAsSubstring = 1) then
  1263.                     Response.Write("<a href=""" & urls(ipage) & "?zoom_highlightsub=" & query_out & """"  & target & ">")
  1264.                 else
  1265.                     Response.Write("<a href=""" & urls(ipage) & "?zoom_highlight=" & query_out & """"  & target & ">")
  1266.                 end if
  1267.             else                      
  1268.                 Response.Write("<a href=""" & urls(ipage) & """"  & target & ">")
  1269.             end if
  1270.             if (Highlighting = 1) then
  1271.                 PrintHighlightDescription(titles(ipage))
  1272.             else
  1273.                 Response.Write(titles(ipage))
  1274.             end if
  1275.             Response.Write("</a>")
  1276.         else
  1277.             Response.Write("<a href=""" & urls(ipage) & """"  & target & ">" & urls(ipage) & "</a>")
  1278.         end if
  1279.  
  1280.         if (UseCats = 1) then
  1281.             catindex = catpages(ipage)
  1282.             Response.Write(" <span class=""category"">[" & catnames(catindex) & "]</span>")
  1283.         end if
  1284.         Response.Write("</div>") & VbCrlf
  1285.  
  1286.         if (DisplayMetaDesc = 1) then
  1287.             ' print meta description
  1288.             if (Len(descriptions(ipage)) > 2) then
  1289.                 Response.Write("<div class=""description"">")
  1290.                 if (Highlighting = 1) then
  1291.                     PrintHighlightDescription(descriptions(ipage))
  1292.                 else
  1293.                     Response.Write(descriptions(ipage))
  1294.                 end if
  1295.                 Response.Write(" <b>...</b></div>") & VbCrlf
  1296.             end if
  1297.         end if
  1298.  
  1299.         if (DisplayContext = 1) then
  1300.             ' extract contextual page description
  1301.             context_keywords = output(2, arrayline)
  1302.             if (context_keywords > MaxContextKeywords) then
  1303.                 context_keywords = MaxContextKeywords
  1304.             end if
  1305.  
  1306.             context_word_count = Int(ContextSize / context_keywords)
  1307.  
  1308.             goback = Int(context_word_count / 2)
  1309.             gobackbytes = goback * MaxDictIDLen
  1310.             if ((gobackbytes / 2) > (context_word_count - context_maxgoback - goback)) then ' 2 is MinDictIDLen
  1311.                 ' go back less if potential for matched word to be outside the context range
  1312.                 ' determine most bytes we should go back to fit the word in in case of all dict ID's were min. len.
  1313.                 gobackbytes = 2 * (context_word_count - context_maxgoback - goback)
  1314.                 ' thus avoiding jumping into the middle of a multi-pair dictID value
  1315.                 goback = Int(gobackbytes / MaxDictIDLen)
  1316.                 ' redetermine max bytes to jump back for this number of words
  1317.                 gobackbytes = goback * MaxDictIDLen
  1318.             end if
  1319.  
  1320.             last_startpos = 0
  1321.             last_endpos = 0
  1322.             FoundContext = 0
  1323.  
  1324.             Response.Write("<div class=""context"">") & VbCrLf
  1325.             for j = 0 to (context_keywords - 1) Step 1
  1326.  
  1327.                 origpos = output(3+j, arrayline)
  1328.                 startpos = origpos
  1329.  
  1330.                 if (gobackbytes < startpos) then
  1331.                     startpos = startpos - gobackbytes
  1332.                     noGoBack = 0
  1333.                 else
  1334.                     noGoBack = 1
  1335.                 end if
  1336.  
  1337.                 'startpos = startpos - (2 * MaxDictIDLen) ' at least 2 words back
  1338.                 'startpos = startpos - gobackbytes
  1339.  
  1340.                 'Response.Write("seeking: " & startpos)
  1341.                 'if (startpos < 0) then
  1342.                 '    startpos = 0
  1343.                 'end if
  1344.  
  1345.                 ' do not overlap with previous extract
  1346.                 if (startpos > last_startpos AND startpos < last_endpos) then
  1347.                     startpos = last_endpos
  1348.                 end if
  1349.  
  1350.                 bin_pagetext.Position = startpos
  1351.                 if (bin_pagetext.EOS = True) then
  1352.                     exit for
  1353.                 end if
  1354.  
  1355.                 'remember last start position
  1356.                 last_startpos = startpos
  1357.  
  1358.                 word_id = GetNextDictWord(bin_pagetext)
  1359.  
  1360.                 context_str = ""
  1361.                 noSpaceForNextChar = False
  1362.  
  1363.                 for i = 0 to context_word_count
  1364.  
  1365.                     if (noSpaceForNextChar = False) then
  1366.                         'if (word_id > DictReservedLimit) then
  1367.                         'No space for reserved words (punctuation, etc)
  1368.                         if (word_id > DictReservedNoSpaces) then
  1369.                             context_str = context_str + " "
  1370.                         elseif (word_id > DictReservedSuffixes AND word_id <= DictReservedPrefixes) then
  1371.                             context_str = context_str + " "
  1372.                             noSpaceForNextChar = True
  1373.                         elseif (word_id > DictReservedPrefixes) then
  1374.                             noSpaceForNextChar = True
  1375.                         end if
  1376.                     else
  1377.                         noSpaceForNextChar = False
  1378.                     end if
  1379.  
  1380.                     if (word_id = 0 OR word_id > dict_count) then
  1381.                         'if (i > goback OR noGoBack = 1) then
  1382.                         if (noGoBack = 1 OR bin_pagetext.Position > origpos) then
  1383.                             exit for
  1384.                         else
  1385.                             context_str = ""
  1386.                             i = 0
  1387.                         end if
  1388.                     else
  1389.                         context_str = context_str + dict(0, word_id)
  1390.                     end if
  1391.  
  1392.                     word_id = GetNextDictWord(bin_pagetext)
  1393.                 next
  1394.  
  1395.                 ' rememeber the last end position
  1396.                 last_endpos = bin_pagetext.Position
  1397.  
  1398.                 if (Trim(titles(ipage)) = Trim(context_str)) then
  1399.                     context_str = ""
  1400.                 end if
  1401.  
  1402.                 if (context_str <> "") then
  1403.                     Response.Write(" <b>...</b> ")
  1404.                     FoundContext = 1
  1405.                     if (Highlighting = 1) then
  1406.                         PrintHighlightDescription(context_str)
  1407.                     else
  1408.                         Response.Write(context_str)
  1409.                     end if
  1410.                 end if
  1411.             next
  1412.             if (FoundContext = 1) then
  1413.                 Response.Write(" <b>...</b>")
  1414.             end if
  1415.             Response.Write("</div>") & VbCrLf
  1416.         end if
  1417.  
  1418.         info_str = ""
  1419.         if (DisplayTerms = 1) then
  1420.             info_str = info_str & STR_RESULT_TERMS_MATCHED & " " & output(2, arrayline)
  1421.         end if
  1422.  
  1423.         if (DisplayScore = 1) then
  1424.             if (len(info_str) > 0) then
  1425.                 info_str = info_str & "  -  "
  1426.             end if
  1427.             info_str = info_str & STR_RESULT_SCORE & " " & score
  1428.         end if
  1429.  
  1430.         if (DisplayDate = 1) then
  1431.             if (len(info_str) > 0) then
  1432.                 info_str = info_str & "  -  "
  1433.             end if
  1434.             info_str = info_str & DatePart("d", datetime(ipage)) & " " & MonthName(DatePart("m", datetime(ipage)), true) & " " & DatePart("yyyy", datetime(ipage))
  1435.         end if
  1436.  
  1437.         if (DisplayURL = 1) then
  1438.             if (len(info_str) > 0) then
  1439.                 info_str = info_str & "  -  "
  1440.             end if
  1441.             info_str = info_str & STR_RESULT_URL & " " & urls(ipage)
  1442.         end if
  1443.  
  1444.         Response.Write("<div class=""infoline"">")
  1445.         Response.Write(info_str)
  1446.         Response.Write("</div>") & VbCrlf
  1447.         arrayline = arrayline + 1
  1448.     loop
  1449.  
  1450.     if (DisplayContext = 1 OR AllowExactPhrase = 1) then
  1451.         bin_pagetext.Close
  1452.     end if
  1453.  
  1454.     'Show links to other result pages
  1455.  
  1456.     if (num_pages > 1) then
  1457.         ' 10 results to the left of the current page
  1458.         start_range = page - 10
  1459.         if (start_range < 1) then
  1460.             start_range = 1
  1461.         end if
  1462.  
  1463.         ' 10 to the right
  1464.         end_range = page + 10
  1465.         if (end_range > num_pages) then
  1466.             end_range = num_pages
  1467.         end if
  1468.  
  1469.         Response.Write("<p></p>" & STR_RESULT_PAGES & " ")
  1470.         if (page > 1) then
  1471.             Response.Write("<a href=""" & selfURL & "?zoom_query=" & query_out & "&zoom_page=" & (page-1) & "&zoom_per_page=" & per_page & "&zoom_cat=" & cat & "&zoom_and=" & andq & "&zoom_sort=" & sort & """><< " & STR_RESULT_PAGES_PREVIOUS & "</a> ")
  1472.         end if
  1473.  
  1474.         'for i = 1 to num_pages
  1475.         for i = start_range to end_range
  1476.             if (Int(i) = Int(page)) then
  1477.                 Response.Write(page & " ")
  1478.             else
  1479.                 Response.Write("<a href=""" & selfURL & "?zoom_query=" & query_out & "&zoom_page=" & i & "&zoom_per_page=" & per_page & "&zoom_cat=" & cat & "&zoom_and=" & andq & "&zoom_sort=" & sort & """>" & i & "</a> ")
  1480.             end if
  1481.         next
  1482.  
  1483.         if (Int(page) <> Int(num_pages)) then
  1484.             Response.Write("<a href=""" & selfURL & "?zoom_query=" & query_out & "&zoom_page=" & (page+1) & "&zoom_per_page=" & per_page & "&zoom_cat=" & cat & "&zoom_and=" & andq & "&zoom_sort=" & sort & """>" & STR_RESULT_PAGES_NEXT & " >></a> ")
  1485.         end if
  1486.     end if
  1487.  
  1488.     Response.Write("</div>") & VbCrLf   ' end results style tag
  1489.  
  1490.     ' Time the searching
  1491.     if (Timing = 1 OR Logging = 1) then
  1492.         ElapsedTime = Timer - StartTime
  1493.         ElapsedTime = Round(ElapsedTime, 3)
  1494.         if (Timing = 1) then
  1495.             Response.Write("<br /><br /><small>" &  STR_SEARCH_TOOK & " " & ElapsedTime & " " & STR_SECONDS & "</small><br />")
  1496.         end if
  1497.     end if
  1498.  
  1499.     'Log the search words, if required
  1500.     if (Logging = 1) then
  1501.         LogQuery = Replace(query, """", """""")
  1502.         DateString = Year(Now) & "-" & Right("0" & Month(Now), 2) & "-" & Right("0" & Day(Now), 2)  & ", " & Right("0" & Hour(Now), 2) & ":" & Right("0" & Minute(Now), 2) & ":" & Right("0" & Second(Now), 2)
  1503.         LogString = DateString & ", " & Request.ServerVariables("REMOTE_ADDR") & ", """ & LogQuery & """, Matches = " & matches
  1504.  
  1505.         if (andq = 1) then
  1506.             LogString = LogString & ", AND"
  1507.         else
  1508.             LogString = LogString & ", OR"
  1509.         end if
  1510.  
  1511.         if (NewSearch = 1) then
  1512.             page = 0
  1513.         end if
  1514.  
  1515.         LogString = LogString & ", PerPage = " & per_page & ", PageNum = " & page
  1516.  
  1517.         if (UseCats = 0) then
  1518.             LogString = LogString & ", No cats"
  1519.         else
  1520.             if (cat = -1) then
  1521.                 LogString = LogString & ", ""Cat = All"""
  1522.             else
  1523.                 logCatStr = catnames(cat)
  1524.                 logCatStr = Replace(logCatStr, """", """""")    ' replace " with ""
  1525.                 LogString = LogString & ", ""Cat = "& logCatStr & """"
  1526.             end if
  1527.         end if
  1528.  
  1529.         ' avoid problems with languages with "," as decimal pt breaking log file format.
  1530.         ElapsedTime = Replace(ElapsedTime, ",", ".")
  1531.         LogString = LogString & ", Time = " & ElapsedTime
  1532.  
  1533.         ' end of record
  1534.         LogString = LogString & VbCrLf
  1535.  
  1536.         on error resume next
  1537.         set logfile = fso.OpenTextFile(MapPath(LogFileName), 8, True, 0)
  1538.         if (Err.Number <> 0) then
  1539.             Response.Write("Unable to write to log file (" & MapPath(LogFileName) & "). Check that you have specified the correct log filename in your Indexer settings and that you have the required file permissions set.<br />")
  1540.         else
  1541.             logfile.Write(LogString)
  1542.             logfile.Close
  1543.         end if
  1544.     end if  ' Logging
  1545.  
  1546. end if  ' NoSearch
  1547.  
  1548. 'Print out the end of the template
  1549. call PrintEndOfTemplate
  1550. %>
  1551.